﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using HYCodeBase.Math;
using HYRevitCode.ElementCreatUtility;
using HYRevitCode.TransactionUtility;
using HYRevitCode.XYZUtility;

namespace RevitInteractiveUtility
{
	public class DoubleCilckToLocate
	{
		public static List<ElementId> DoubleClickToLocate(UIDocument uiDoc, Autodesk.Revit.DB.View view, Element elementToLocate, Autodesk.Revit.DB.Document currenDoc, bool isAddBoundingBox = false)
		{
			List<ElementId> result = new List<ElementId>();
			if (!uiDoc.ActiveView.Id.Equals(view.Id))
			{
				uiDoc.ActiveView = view;
			}
			Document document = elementToLocate.Document;
			if (currenDoc.Equals(document))
			{
				uiDoc.ShowElements(elementToLocate);
				List<Element> list = new List<Element>();
				list.Add(elementToLocate);
				BoundingBoxXYZ item = elementToLocate.get_BoundingBox(null);
				RevitVersionFuncs.SetSelection(uiDoc.Selection, list);
				List<object> list2 = new List<object>();
				list2.Add(view);
				list2.Add(item);
				Exception ex;
				RevitTransactionManger.DoTransaction(uiDoc.Document, new TransactionWorkDelegate(DoubleCilckToLocate.ChangeViewSectionBox), list2, out ex, false, null);
				return result;
			}
			DoubleCilckToLocate.LinkDocDoubleClickToLocate(currenDoc, elementToLocate, uiDoc, isAddBoundingBox);
			return result;
		}

		private static bool ChangeViewSectionBox(object input)
		{
			DoubleCilckToLocate.ChangeViewSectionBox((input as List<object>)[0] as View, (input as List<object>)[1] as BoundingBoxXYZ);
			return true;
		}

		private static void ChangeViewSectionBox(Autodesk.Revit.DB.View inputView, BoundingBoxXYZ inputBoundingBox)
		{
			if (inputView == null || inputBoundingBox == null)
			{
				return;
			}
			if (inputView is View3D)
			{
				DoubleCilckToLocate.ChangeViewSectionBox(inputView as View3D, inputBoundingBox);
				return;
			}
			if (inputView is ViewPlan)
			{
				DoubleCilckToLocate.ChangeViewSectionBox(inputView as ViewPlan, inputBoundingBox);
			}
		}

		private static void ChangeViewSectionBox(ViewPlan inputView, BoundingBoxXYZ inputBoundingBox)
		{
		}

		private static void ChangeViewSectionBox(View3D inputView, BoundingBoxXYZ inputBoundingBox)
		{
			BoundingBoxXYZ sectionBox = inputView.GetSectionBox();
			XYZ max = sectionBox.Max;
			XYZ inputValue = sectionBox.Min;
			max.SetY(inputBoundingBox.Max.Y);
			inputValue = inputValue.SetY(inputBoundingBox.Min.Z);
			inputView.SetYJKSectionBox(sectionBox);
		}

		private static List<ElementId> LinkDocDoubleClickToLocate(Autodesk.Revit.DB.Document doc, Element elementToLocate, UIDocument uiDoc, bool isAddBoundingBox)
		{
			List<ElementId> result = new List<ElementId>();
			Autodesk.Revit.DB.View activeView = doc.ActiveView;
			BoundingBoxXYZ boundingBoxXYZ = elementToLocate.get_BoundingBox(activeView);
			if (boundingBoxXYZ == null)
			{
				return result;
			}
			UIView uiview = null;
			foreach (UIView uiview2 in uiDoc.GetOpenUIViews())
			{
				if (uiview2.ViewId.Equals(activeView.Id))
				{
					uiview = uiview2;
					break;
				}
			}
			uiview.ZoomAndCenterRectangle(boundingBoxXYZ.Min, boundingBoxXYZ.Max);
			if (isAddBoundingBox)
			{
				List<Element> list = new List<Element>();
				result = DoubleCilckToLocate.CreateModelCurve(doc, boundingBoxXYZ, ref list);
				if (list.Count > 0)
				{
					RevitVersionFuncs.SetSelection(uiDoc.Selection, list);
				}
			}
			List<object> list2 = new List<object>();
			list2.Add(activeView);
			list2.Add(boundingBoxXYZ);
			Exception ex;
			RevitTransactionManger.DoTransaction(uiDoc.Document, new TransactionWorkDelegate(DoubleCilckToLocate.ChangeViewSectionBox), list2, out ex, false, null);
			return result;
		}

		private static List<ElementId> CreateModelCurve(Autodesk.Revit.DB.Document doc, BoundingBoxXYZ box, ref List<Element> lstCurve)
		{
			GraphicsStyle gStyle = LineTypeCreatUtilityMethod.CreateLineType(doc, DoubleCilckToLocate.m_sLineTypeName, new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0), 1);
			List<ElementId> list = new List<ElementId>();
			XYZ xyz = box.Min + DoubleCilckToLocate.minOffset;
			XYZ xyz2 = box.Max + DoubleCilckToLocate.maxOffset;
			XYZ xyz3 = xyz;
			XYZ xyz4 = new XYZ(xyz2.X, xyz.Y, xyz3.Z);
			XYZ xyz5 = new XYZ(xyz.X, xyz2.Y, xyz3.Z);
			XYZ xyz6 = new XYZ(xyz2.X, xyz2.Y, xyz3.Z);
			XYZ xyz7 = new XYZ(xyz.X, xyz.Y, xyz2.Z);
			XYZ xyz8 = new XYZ(xyz2.X, xyz.Y, xyz7.Z);
			XYZ xyz9 = new XYZ(xyz.X, xyz2.Y, xyz7.Z);
			XYZ xyz10 = new XYZ(xyz2.X, xyz2.Y, xyz7.Z);
			List<KeyValuePair<XYZ, XYZ>> list2 = new List<KeyValuePair<XYZ, XYZ>>();
			list2.Add(new KeyValuePair<XYZ, XYZ>(xyz3, xyz4));
			list2.Add(new KeyValuePair<XYZ, XYZ>(xyz4, xyz6));
			list2.Add(new KeyValuePair<XYZ, XYZ>(xyz6, xyz5));
			list2.Add(new KeyValuePair<XYZ, XYZ>(xyz5, xyz3));
			List<KeyValuePair<XYZ, XYZ>> list3 = new List<KeyValuePair<XYZ, XYZ>>();
			list3.Add(new KeyValuePair<XYZ, XYZ>(xyz7, xyz8));
			list3.Add(new KeyValuePair<XYZ, XYZ>(xyz8, xyz10));
			list3.Add(new KeyValuePair<XYZ, XYZ>(xyz10, xyz9));
			list3.Add(new KeyValuePair<XYZ, XYZ>(xyz9, xyz7));
			List<KeyValuePair<XYZ, XYZ>> list4 = new List<KeyValuePair<XYZ, XYZ>>();
			list4.Add(new KeyValuePair<XYZ, XYZ>(xyz7, xyz3));
			list4.Add(new KeyValuePair<XYZ, XYZ>(xyz10, xyz6));
			List<KeyValuePair<XYZ, XYZ>> list5 = new List<KeyValuePair<XYZ, XYZ>>();
			list5.Add(new KeyValuePair<XYZ, XYZ>(xyz8, xyz4));
			list5.Add(new KeyValuePair<XYZ, XYZ>(xyz9, xyz5));
			list.AddRange(DoubleCilckToLocate.CreateModelCurve(doc, gStyle, list2, ref lstCurve));
			list.AddRange(DoubleCilckToLocate.CreateModelCurve(doc, gStyle, list3, ref lstCurve));
			list.AddRange(DoubleCilckToLocate.CreateModelCurve(doc, gStyle, list4, ref lstCurve));
			list.AddRange(DoubleCilckToLocate.CreateModelCurve(doc, gStyle, list5, ref lstCurve));
			return list;
		}

		private static List<ElementId> CreateModelCurve(Autodesk.Revit.DB.Document doc, GraphicsStyle gStyle, List<KeyValuePair<XYZ, XYZ>> points, ref List<Element> lstCurve)
		{
			List<ElementId> list = new List<ElementId>();
			if (points.Count == 0)
			{
				return new List<ElementId>();
			}
			Transaction transaction = new Transaction(doc, "Create ModelCurve");
			try
			{
				transaction.Start();
				foreach (KeyValuePair<XYZ, XYZ> keyValuePair in points)
				{
					XYZ key = keyValuePair.Key;
					XYZ value = keyValuePair.Value;
					XYZ xyz = (value - key).Normalize();
					XYZ basisX;
					if (MathUtility.IsEqual(key.Z, value.Z))
					{
						basisX = xyz.CrossProduct(XYZ.BasisZ);
					}
					else
					{
						basisX = xyz.CrossProduct(XYZ.BasisX);
					}
					xyz.CrossProduct(XYZ.BasisZ);
					Plane plane = RevitVersionFuncs.CreatePlanByOriginAndBasis(key, basisX, xyz);
					SketchPlane sketchPlane = SketchPlane.Create(doc, plane);
					Curve curve = Line.CreateBound(keyValuePair.Key, keyValuePair.Value);
					curve.SetGraphicsStyleId(gStyle.Id);
					ModelCurve modelCurve = doc.Create.NewModelCurve(curve, sketchPlane);
					modelCurve.LineStyle = gStyle;
					list.Add(modelCurve.Id);
					lstCurve.Add(modelCurve);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
				return new List<ElementId>();
			}
			return list;
		}

		private static XYZ minOffset = new XYZ(UnitUtility.MMToFeet(-10.0), UnitUtility.MMToFeet(-10.0), UnitUtility.MMToFeet(-10.0));

		private static XYZ maxOffset = new XYZ(UnitUtility.MMToFeet(10.0), UnitUtility.MMToFeet(10.0), UnitUtility.MMToFeet(10.0));

		private static string m_sLineTypeName = "DoubleClickBoxCurve";
	}
}
